package mapelements;


import java.io.Serializable;

/**rappresenta un generico elemento della mappa: ogni elemento della mappa possiede un concept cioe'
 * un oggetto che contiene la <strong>logica</strong> dell'elemento ed un renderer che ne contiene la
 * <strong>grafica</strong>.
 * <p>la parte concettuale della classe risiede nella classe figlia che estende questa classe. Il renderer, invece
 * è un semplice attributo della classe che può essere opportunamente pilotato dalla parte concettuale
 * 
 * @author koldar
 * @version 1.3
 *
 * @param <RENDERER> indica il tipo della parte grafica. Deve estendere Renderer
 */
public abstract class MapElement<RENDERER extends Renderer> implements Serializable,Cloneable{

	private static final long serialVersionUID = -5676437743503880375L;
	/**indica la parte grafica della mappa. Indica come l'element deve essere disegnato*/
	private RENDERER renderer;
	
	public MapElement(RENDERER r){
		this.renderer=r;
	}
	
	/**costruisce il nuovo MapElement senza però settare il suo renderer
	 * 
	 */
	public MapElement(){
		this(null);
	}

	/**
	 * @return the renderer. For further information visit {@link #renderer}
	 */
	public RENDERER getRenderer() {
		return renderer;
	}

	/**
	 * @param renderer the renderer to set
	 */
	public void setRenderer(RENDERER renderer) {
		this.renderer = renderer;
	}
	/**
	 * 
	 * @return una stringa che tenta di rappresentare in modo intuitivo il MapElement. Di default è semplicemente il nome della classe
	 */
	public String generateProperKey(){
		return this.getClass().getSimpleName();
	}
	
	@Override
	public MapElement<RENDERER> clone() throws CloneNotSupportedException{
		MapElement<RENDERER> result=(MapElement<RENDERER>)super.clone();
		result.renderer=(RENDERER)this.renderer.clone();
		return result;
	}
	/**esegue le istruzioni per avviare eventuali thread del Concept del MapElement. Di default il
	 * metodo esegue il metodo start del Renderer; 
	 * 
	 */
	public void start(){
		try{
			this.getRenderer().start();
		}catch(NullPointerException renderernull){}
	}
	
	/**esegue le istruzioni per terminare eventuali thread del Concept del MapElement. Di default
	 * il metodo esegue il metodo temrinate del Renderer
	 * 
	 */
	public void terminate(){
		try{
			this.getRenderer().terminate();
		}catch(NullPointerException renderernull){}
	}
	

}
